package net.lab1024.sa.admin.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.dongliu.requests.Requests;
import net.dongliu.requests.body.Part;
import net.lab1024.sa.admin.module.crawler.domain.jddj.JdItemDto;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import net.lab1024.sa.base.constant.RedisKeyConst;
import net.lab1024.sa.base.module.support.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class JddjUtils {
    @Autowired
    RedisService redisService;
    @Autowired
    ImageUtils imageUtils;


    public JSONArray getShopList(String cookieStr) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.o2o.order.home.getData";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");
        String respText = Requests.post(url)
                .timeout(30000)
                .cookies(cookieToMap)
                .headers(heardMap)
                .jsonBody("{}")
                .send().readToText();
        JSONObject result = JSONObject.parseObject(respText).getJSONObject("result");
        String logoUrl = result.getString("logoUrl");
        String listUrl = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.store.manage.storeNew" +
                ".queryPageList";
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"stationName\":\"\",\"pageSize\":10,\"pageNo\":1,\"pageSizes\":[1,10," +
                "20,30,40,50,100,200],\"stationNos\":[],\"venderIds\":[]}");
        String respText1 = Requests.post(listUrl)
                .cookies(cookieToMap)
                .timeout(30000)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        log.info("获取京东店铺列表:{}", respText1);
        JSONArray dataList = JSONObject.parseObject(respText1).getJSONObject("result").getJSONArray("list");
        if (!CollectionUtils.isEmpty(dataList)) {
            dataList.stream().map(dataObj -> (JSONObject) dataObj).forEach(dataObj -> {
                dataObj.put("logoUrl", logoUrl);
            });
            return dataList;
        } else {
            throw new BusinessException("找不到门店;请检查!");
        }
    }

    /**
     * 创建分类
     *
     * @param cookieStr
     * @return
     */
    public String getTagList(String cookieStr) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.shop.categoryList";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");
        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .timeout(30000)
                .headers(heardMap)
                .jsonBody("{}")
                .send().readToText();
        return respText;
    }

    public String createTag(String cookieStr, String name) {
        name = name.trim();
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.shop.saveStoreCategory";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"shopCategoryId\":\"\",\"pid\":0,\"shopCategoryName\":\"" + name + "\",\"iconUrl" +
                "\":\"\",\"imgUrl\":\"\",\"shopCategoryLevel\":1,\"categoryType\":null}");
        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .timeout(30000)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return respText;
    }

    /**
     * 根据商品名称获取推荐分类
     *
     * @param cookieStr
     * @param name
     * @return
     */
    public String getCategoryRecommend(String cookieStr, String name) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.merchantCategory.pms" +
                ".getCategoryRecommend";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"firstCategoryId\":0,\"secondCategoryId\":0,\"categoryId\":0,\"skuName\":\"" + name +
                "\",\"brandId\":\"\"}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return respText;
    }


    public String getCategoryInfoByPid(String cookieStr, Long pid, int lev) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.merchantCategory.pms" +
                ".getCategoryInfoByPid";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"lev\":" + lev + ",\"pid\":" + pid + "}");
        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return respText;
    }


    public Boolean checkSaleAttrByCategoryId(String cookieStr, Long id) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        ;
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.enterprise.spu" +
                ".checkSaleAttrByCategoryId";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"categoryId\":" + id + "}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return respText.contains("成功");
    }

    public List<String> getWaimaiRandomCategory(String cookieStr) {
        String categorys = redisService.get(RedisKeyConst.Support.JDWAIMAI_MEISHI_CATEGORY);
        //外卖美食类
        List<String> categoryIds = null;
        if (StringUtils.isBlank(categorys)) {
            categoryIds = new ArrayList<>();
            getCategoryInfoByPid(cookieStr, 31061L, 1, categoryIds);
        } else {
            categoryIds = JSONArray.parseArray(categorys, String.class);
        }
        if (CollectionUtils.isEmpty(categoryIds)) {
            //其他现制饭类
            categoryIds.add("31061,31190,31204");
        }
        return categoryIds;
    }

    public String getSaleAttrByCategoryIdAndSuperId(String cookieStr, Long id) {
        if (id == null) {
            return "[]";
        }
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.enterprise.spu" +
                ".getSaleAttrByCategoryIdAndSuperId";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"categoryId\":" + id + "}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return JSONObject.parseObject(respText).getJSONArray("result").toJSONString();
    }

    public void getCategoryInfoByPid(String cookieStr, Long pid, int lev, List<String> categoryIds) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.merchantCategory.pms" +
                ".getCategoryInfoByPid";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"lev\":" + lev + ",\"pid\":" + pid + "}");
        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        JSONArray result = JSONObject.parseObject(respText).getJSONArray("result");
        if (CollectionUtils.isEmpty(result)) {
            return;
        }

        result.stream().map(r -> (JSONObject) r).forEach(r -> {
            String categoryName = r.getString("categoryName");
            if (!categoryName.equals("食物加料") && !categoryName.equals("非食品类")) {
                if (r.getInteger("leaf")==null||r.getInteger("leaf") != 1) {
                    getCategoryInfoByPid(cookieStr, r.getLong("id"), r.getIntValue("categoryLevel") + 1, categoryIds);
                } else {
                    String fullPath = r.getString("fullPath");
                    if (StringUtils.isNoneBlank(fullPath)) {
                        if (checkSaleAttrByCategoryId(cookieStr, r.getLong("id"))) {
                            categoryIds.add(fullPath);
                        }
                    }
                }
            }
        });
    }


    public String uploadImg(String cookieStr, String url) {
        String pt = (url.contains("meituan") || cookieStr.contains("meituan")) ? "mt" : "eb";
        String newUrl = "";
        if (url.endsWith(".jpg.webp") || url.endsWith(".png.webp")) {
            url = url.substring(0, url.indexOf(".webp"));
        }
        URI uri = URI.create(url);
        Path path = Paths.get(uri.getPath());
        String suffix = path.getFileName().toString();
        if (!suffix.contains(".")) {
            suffix += ".png";
        }
        File tempFile = FileUtil.createTempFile(suffix, true);
        if (suffix.endsWith(".jpg.webp") || suffix.endsWith(".png.webp")) {
            url = url.substring(0, url.indexOf(".webp"));
        }
        if (pt.equals("mt") && StringUtils.isNoneBlank(url) && !url.endsWith(".gif") && !url.contains("@watermark=1")) {
            url += "@watermark=1&&object=L3dtcHJvZHVjdC9kZWJiN2M1ZTgyZjJiNjU4Y2ZmNzA1ZTg1N2FjOTcwYjgxLnBuZw==";
        }
        HttpUtil.downloadFile(url, tempFile, 60000);

        try {
            if (suffix.endsWith(".gif")) {
                tempFile = imageUtils.readGifFirst(tempFile);
            } else if (suffix.endsWith(".webp")) {
                File newTempFile = FileUtil.createTempFile(".png", true);
                imageUtils.webpmux(tempFile.getAbsolutePath(), newTempFile.getAbsolutePath());
                FileUtil.del(tempFile);
                tempFile = newTempFile;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        imageUtils.resizeImageAll(tempFile, 800, 800);
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String reqUrl = "https://common-upload.jddj.com/upload/file";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("secretkey", getKey());
        heardMap.put("referer", "https://store.jddj.com/");
        String respText = Requests.post(reqUrl)
                .cookies(cookieToMap)
                .headers(heardMap)
                .timeout(60000)
                .multiPartBody(Part.file("file", tempFile))
                .send().readToText();
        log.info("上传图片结果:{}", respText);
        JSONObject result = null;
        try {
            result = JSONObject.parseObject(respText).getJSONObject("result");
        } catch (Exception e) {
            respText = Requests.post(reqUrl)
                    .cookies(cookieToMap)
                    .timeout(60000)
                    .headers(heardMap)
                    .multiPartBody(Part.file("file", tempFile))
                    .send().readToText();
            log.info("上传图片结果:{}", respText);
        }
        String uploadImgUrl = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.merchant" +
                ".uploadImg";
        FileUtil.del(tempFile);
        Map<String, Object> bodyMap = new HashMap<>();
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("fileUrl", result.getString("url"));
        bodyJson.put("filePath", result.getString("path"));
        bodyMap.put("body", bodyJson.toJSONString());
        heardMap.remove("secretkey");
        respText = Requests.post(uploadImgUrl)
                .timeout(60000, 60000)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        log.info("获取图片结果:{}", respText);
        newUrl = JSONObject.parseObject(respText).getString("result");
        if (StringUtils.isNoneBlank(newUrl) && !newUrl.endsWith("webp")) {
            return "/" + newUrl;
        }
        if (StringUtils.isNoneBlank(newUrl) && newUrl.endsWith("webp")) {
            return "";
        }
        return "/" + JSONObject.parseObject(respText).getString("result");
    }


    /**
     * 获取类目属性
     *
     * @param cookieStr
     * @param id
     * @return
     */
    public String getCategoryAttr(String cookieStr, Long id) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.merchantCategory.pms" +
                ".getCategoryAttr";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"categoryId\":" + id + "}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        return JSONObject.parseObject(respText).getJSONArray("result").toJSONString();
    }

    public JSONObject saveSpuProductInfo(String cookieStr, JdItemDto item) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://common-upload.jddj.com/upload/file";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("secretkey", getKey());
        heardMap.put("referer", "https://store.jddj.com/");

        File tempFile = FileUtil.createTempFile(".json", true);
        FileUtil.writeUtf8String(JSONObject.toJSONString(item), tempFile.getAbsolutePath());
        //log.info("商品数据:{}", JSONObject.toJSONString(item));
        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .multiPartBody(Part.file("file", "data.json", tempFile),
                        Part.param("Content-Type", "application/json")
                )
                .send().readToText();
        log.info("保存商品:{},json结果:{}", item.getTitle(), respText);
        JSONObject uploadResultObj = JSONObject.parseObject(respText).getJSONObject("result");
        String saveUrl = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.enterprise.spu" +
                ".saveSpuProductInfo";
        Map<String, Object> bodyMap = new HashMap<>();
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("fileUrl", uploadResultObj.getString("url"));
        bodyJson.put("filePath", uploadResultObj.getString("path"));
        bodyMap.put("body", bodyJson.toJSONString());
        heardMap.remove("secretkey");
        respText = Requests.post(saveUrl)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        log.info("添加商品:{},结果:{}", item.getTitle(), respText);
        JSONObject resultObj = JSONObject.parseObject(respText);
        FileUtil.del(tempFile);
        return resultObj;
    }


    public JSONArray skuQuery(String cookieStr, String name, int count) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.o2o.shop.promo.sku.skuQuery";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"skuIds\":\"\",\"upcCodes\":\"\",\"skuName\":\"" + name + "\",\"skuId\":\"\"," +
                "\"categoryOneId\":\"\",\"categoryTwoId\":\"\",\"allStation\":true,\"stationNos\":[],\"pageNo\":1," +
                "\"pageSize\":10}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        if (respText.contains("出错啦")) {
            if (count < 5) {
                return skuQuery(cookieStr, name, ++count);
            } else {
                return null;
            }
        }
        log.info("获取SKU:{},列表:{}", name, respText);
        return JSONObject.parseObject(respText).getJSONObject("result").getJSONArray("resultList");
    }

    public JSONArray querySpuList(String cookieStr, String name, int count) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.enterprise.spu.querySpuList";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"wareName\":\"" + name + "\",\"skuId\":\"\",\"outSuperId\":\"\",\"upcCode\":\"\",\"fixedStatus\":\"\",\"shopCategoryLevel1\":\"\",\"shopCategoryLevel2\":\"\",\"shopCategoryLevel3\":\"\",\"categoryInfoList\":[],\"skuCreateSource\":\"\",\"pageNo\":1,\"pageSize\":10}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        if (respText.contains("出错啦")) {
            if (count < 5) {
                return querySpuList(cookieStr, name, ++count);
            } else {
                return null;
            }
        }
        log.info("获取SPU:{},列表:{}", name, respText);
        return JSONObject.parseObject(respText).getJSONObject("result").getJSONArray("resultList");
    }

    public void updateWareUpStatus(String cookieStr, List<Long> ids, int status) {
        Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
        String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.pms.web.enterprise.spu" +
                ".updateWareUpStatus";
        Map<String, String> heardMap = new HashMap<>();
        heardMap.put("dsm-platform", "pc");
        heardMap.put("referer", "https://store.jddj.com/");

        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("body", "{\"wareIds\":[" + StringUtils.join(ids, ",") + "],\"fixedStatus\":" + status + "}");

        String respText = Requests.post(url)
                .cookies(cookieToMap)
                .headers(heardMap)
                .body(bodyMap)
                .send().readToText();
        log.info("修改商品状态:{},结果:{}", ids.size(), respText);
    }

    public void updateCurrentQty(String cookieStr, String skuId, String shopId, Integer currentQty) {
        if (StringUtils.isNotBlank(skuId)) {
            Map<String, String> cookieToMap = SmartStringUtil.cookieStrConvert(cookieStr);
            String url = "https://sff.jddj.com/api?v=1.0&appId=YNE4XWZFDHXOYGKZU5FN&api=dsm.stock.web.stock" +
                    ".updateCurrentQty";
            Map<String, String> heardMap = new HashMap<>();
            heardMap.put("dsm-platform", "pc");
            heardMap.put("referer", "https://store.jddj.com/");

            String respText = Requests.post(url)
                    .cookies(cookieToMap)
                    .headers(heardMap)
                    .jsonBody(JSONObject.parseObject("{\"skuId\":" + skuId + ",\"stationNo\":\"" + shopId + "\"," +
                            "\"currentQty\":" + currentQty +
                            "}"))
                    .send().readToText();
            log.info("设置skuId:{},库存:{}", skuId, respText);
        }
    }

    private String getKey() {
        String content = System.currentTimeMillis() + "";
        AES aes = new AES("ECB", "PKCS7Padding",
                "JD1B3JP6U8O0EFDJ".getBytes());

        // 加密为16进制表示
        String encryptHex = aes.encryptBase64(content);
        return encryptHex;
    }

    public void checkResult(JSONObject responObj) {
        if (responObj.getInteger("code") != 0) {
            throw new BusinessException(responObj.getString("msg"));
        }
    }
}
